Imports System.IO
Imports System.Text
Imports System.Xml
Imports System.Xml.Serialization
Imports System.ComponentModel
Imports System.Windows.Forms.Design
Imports System.Linq
Imports System.IO.IsolatedStorage


Public Class mainForm

    Const _stationFile As String = "qtstations.xml"
    Dim WithEvents _radio As Radio

#Region "Radio events handler"

    Private Sub radio_StationChanged(ByVal sender As Object, ByVal e As EventArgs) Handles _radio.StationChanged

        stationsList.Text = _radio.CurrentStation.ToString()

    End Sub

    Private Sub radio_PlayStateChanged(ByVal sender As Object, ByVal e As EventArgs) Handles _radio.PlayStateChanged

        If _radio.IsPlaying Then
            playButton.Image = My.Resources.stopIcon
            playMenu.Image = My.Resources.stopIcon
            playMenu.Text = "Stop"

        Else
            playButton.Image = My.Resources.playIcon
            playMenu.Image = My.Resources.playIcon
            playMenu.Text = "Play"

        End If

    End Sub

#End Region

#Region "Toolbar and menu handlers"
    Private Sub playButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles playButton.Click
        _radio.PlayToggle()
    End Sub

    Private Sub quitButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles quitButton.Click
        quit()
    End Sub

    Private Sub nextMenu_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        _radio.NextStation()
    End Sub

    Private Sub prevMenu_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        _radio.PreviousStation()
    End Sub

    Private Sub playMenu_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles playMenu.Click
        _radio.PlayToggle()
    End Sub

    Private Sub quitMenu_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles quitMenu.Click
        quit()
    End Sub

    'these events are handled dynamically ------------------------------

    Private Sub editButton_Click(ByVal sender As Object, ByVal e As EventArgs)
        openEditForm()
    End Sub

    Private Sub stationButton_Click(ByVal sender As Object, ByVal e As EventArgs)

        Dim ts As ToolStripItem = DirectCast(sender, ToolStripItem)
        Dim os As OnlineStation = DirectCast(ts.Tag, OnlineStation)

        _radio.GotoStation(os)

    End Sub

#End Region

#Region "Animation Effects"

    Private _targetOpacity As Double = 0.75
    Private Const lowOpacity As Double = 0.75
    Private Const highOpacity As Double = 1.0
    Private Const opacityAnimSpeed As Double = 1.2
    Private Const opacityDiffThreashold As Double = 0.01

    Private Sub controlStrip_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles controlStrip.MouseEnter
        _targetOpacity = highOpacity
        animationTimer.Start()
    End Sub

    Private Sub controlStrip_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles controlStrip.MouseLeave
        _targetOpacity = lowOpacity
        animationTimer.Start()
    End Sub

    Private Sub animationTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles animationTimer.Tick

        'find the differences
        Dim diff = _targetOpacity - Me.Opacity

        'if reached the diff threshold then stop the animation
        If Math.Abs(diff) < opacityDiffThreashold Then
            animationTimer.Stop()
            Return
        End If

        'else perform one more animation step
        Me.Opacity = Me.Opacity + (diff / opacityAnimSpeed) 'cubic tween

    End Sub

#End Region

#Region "Init and quit functions"

    Sub init()

        'initialize radio engine
        _radio = New QuickTuner.Radio()

        'look for the station file
        If FileStore.ContainsFile(_stationFile) Then

            'loads from the file if the file exists
            Using fs = FileStore.OpenFileStream(_stationFile, FileMode.Open)
                _radio.LoadStationList(fs)
                fs.Close()
            End Using

        Else 'add a dummy station to tell the user to start
            _radio.Stations.Add(New OnlineStation("Please configure your preferred stations.", "about:blank"))

        End If

        'update UI to display loaded list of stations
        updateStationList()

        'sets the tray icon
        trayIcon.Icon = My.Resources.mp3Icon

    End Sub

    Sub quit()

        'save station list to the filestore
        Using fs = FileStore.OpenFileStream(_stationFile, FileMode.Create)
            _radio.SaveStationList(fs)
            fs.Close()
        End Using

        'truncate the cache size
        FileStore.TruncateCache(My.Settings.maximumCacheSize)

        'clear tray icon
        trayIcon.Dispose()

        'close the main form (this form)
        Me.Close()

        'End 'closing main form ends the application

    End Sub

#End Region

#Region "Playlist events handler"

    Protected WithEvents _editForm As editForm
    Protected _editFormVisible As Boolean
    Sub openEditForm()

        If Not _editFormVisible Then
            If (_editForm Is Nothing) OrElse _editForm.IsDisposed Then _
                _editForm = New editForm(_radio)
            _editForm.Show()
            _editFormVisible = True

        Else
            _editForm.Activate()

        End If

    End Sub

    Private Sub _editForm_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles _editForm.FormClosed
        If _editForm.IsDirty Then updateStationList()
        _editFormVisible = False
    End Sub

    Sub updateStationList()

        stationsMenu.Image = My.Resources.mp3Icon.ToBitmap()

        'clear all items and rebuild
        stationsList.DropDownItems.Clear()
        stationsMenu.DropDownItems.Clear()
        For Each os As OnlineStation In _radio.Stations

            'creates new toolstripitem and bind it to the station change handler
            Dim tsi = stationsList.DropDownItems.Add(os.ToString, Nothing, _
                New EventHandler(AddressOf Me.stationButton_Click))

            'sets the image url so it start downloading the image
            tsi.SetImageLocation(os.FavIconURL)

            'attach the original OnlineStation instance for later reference
            tsi.Tag = os

            'do the same for tray menu
            tsi = stationsMenu.DropDownItems.Add(os.ToString(), Nothing, _
                New EventHandler(AddressOf Me.stationButton_Click))
            tsi.SetImageLocation(os.FavIconURL)
            tsi.Tag = os

        Next

        'add a separator a "edit station" menu item with italic text
        'and bind it to editButton_Click
        'tray menu already has one, so only initialize the toolbar dropdown
        stationsList.DropDownItems.Add("-")
        With stationsList.DropDownItems.Add("Edit stations...", Nothing, New EventHandler(AddressOf Me.editButton_Click))
            .Image = My.Resources.editIcon
        End With

        'updates the title if radio is already playing
        If _radio.IsPlaying Then
            stationsList.Text = _radio.CurrentStation.Title
        End If

    End Sub

#End Region

#Region "Form dragging handler"

    Dim _dragRef As Point

    Private Sub gripStrip_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles gripStrip.MouseDown
        _dragRef = e.Location
    End Sub

    Private Sub gripStrip_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles gripStrip.MouseLeave
        If Control.MouseButtons = Windows.Forms.MouseButtons.Left Then
            Me.Location += controlStrip.PointToClient(Control.MousePosition) - _dragRef
            '_dragref = control.mouseposition
        End If
    End Sub

    Private Sub gripStrip_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles gripStrip.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            Me.Location += e.Location - _dragRef
            '_dragRef = controlStrip.PointToScreen(e.Location)
        End If
    End Sub

#End Region

    'misc event handlers -------------------------------------

    Private Sub mainForm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        init()
    End Sub

    Private Sub trayIcon_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles trayIcon.MouseClick
        If e.Button = Windows.Forms.MouseButtons.Left Then _
            Me.Visible = Not Me.Visible
    End Sub

    Private Sub editMenu_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles editMenu.Click
        openEditForm()
    End Sub

End Class
